#!/bin/sh
#
# git-flow -- A collection of Git extensions to provide high-level
# repository operations for Vincent Driessen's branching model.
#
# A blog post presenting this model is found at:
#    http://blog.avirtualhome.com/development-workflow-using-git/
#
# Feel free to contribute to this project at:
#    http://github.com/CJ-Systems/gitflow-cjs
#
# Authors:
# Copyright 2003 CJ Systems. All rights reserved.
# Copyright 2012-2019 Peter van der Does. All rights reserved.
#
# Original Author:
# Copyright 2010 Vincent Driessen. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# enable debug mode
if [ "$DEBUG" = "yes" ]; then
	set -x
fi

# Setup the GITFLOW_DIR for different operating systems.
# This is mostly to make sure that we get the correct directory when the
# git-flow file is a symbolic link
case $(uname -s) in
Linux)
	export GITFLOW_DIR=$(dirname "$(readlink -f "$0")")
	;;
FreeBSD|OpenBSD|NetBSD)
	export FLAGS_GETOPT_CMD='/usr/local/bin/getopt'
	export GITFLOW_DIR=$(dirname "$(realpath "$0")")
	;;
Darwin)
	PRG="$0"
	while [ -h "$PRG" ]; do
		link=$(readlink "$PRG")
		if expr "$link" : '/.*' > /dev/null; then
			PRG="$link"
		else
			PRG="$(dirname "$PRG")/$link"
		fi
	done
	export GITFLOW_DIR=$(dirname "$PRG")
	;;
*MINGW*)
	export GITFLOW_DIR=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
	pwd () {
		builtin pwd -W
	}
	;;
*)
	# The sed expression here replaces all backslashes by forward slashes.
	# This helps our Windows users, while not bothering our Unix users.)
	export GITFLOW_DIR=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
	;;
esac

# Extra environment settings
if [ -f ~/.gitflow_export ]; then
	if grep -E 'GITFLOW_FLAG_(SHOWCOMMANDS|INIT|FEATURE|HOTFIX|RELEASE|SUPPORT)' ~/.gitflow_export > /dev/null; then
		echo "Using environment variables for \"showcommands\", \"init\", \"feature\", \"hotfix\", \"release\" and \"support\" in ~/.gitflow_export has deprecated, use git config instead."
		echo ""
		exit 1;
	else
		. ~/.gitflow_export
	fi
fi

usage() {
	echo "usage: git flow <subcommand>"
	echo
	echo "Available subcommands are:"
	echo "   init      Initialize a new git repo with support for the branching model."
	echo "   feature   Manage your feature branches."
	echo "   bugfix    Manage your bugfix branches."
	echo "   release   Manage your release branches."
	echo "   hotfix    Manage your hotfix branches."
	echo "   support   Manage your support branches."
	echo "   version   Shows version information."
	echo "   config    Manage your git-flow configuration."
	echo "   log       Show log deviating from base branch."
	echo
	echo "Try 'git flow <subcommand> help' for details."
}

main() {
	if [ $# -lt 1 ]; then
		usage
		exit 1
	fi

	# Use the shFlags project to parse the command line arguments
	. "$GITFLOW_DIR/gitflow-shFlags"
	FLAGS_PARENT="git flow"

	# Load common functionality
	. "$GITFLOW_DIR/gitflow-common"

	# allow user to request git action logging
	DEFINE_boolean 'showcommands' false 'Show actions taken (git commands)'
	# but if the user prefers that the logging is always on,
	# use the environmental variables.
	gitflow_override_flag_boolean 'showcommands' 'showcommands'

	# Sanity checks
	SUBCOMMAND="$1"; shift
	if [ "${SUBCOMMAND}" = "finish" ] || [ "${SUBCOMMAND}" = "delete" ] || [ "${SUBCOMMAND}" = "publish" ] || [ "${SUBCOMMAND}" = "rebase" ]; then
		_current_branch=$(git_current_branch)
		if gitflow_is_prefixed_branch "${_current_branch}"; then
			if startswith "${_current_branch}" $(git config --get gitflow.prefix.feature); then
				SUBACTION="${SUBCOMMAND}"
				SUBCOMMAND="feature"
				_prefix=$(git config --get gitflow.prefix.feature)
				_short_branch_name=$(echo ${_current_branch#*${_prefix}})
			else
				if startswith "${_current_branch}" $(git config --get gitflow.prefix.bugfix); then
					SUBACTION="${SUBCOMMAND}"
					SUBCOMMAND="bugfix"
					_prefix=$(git config --get gitflow.prefix.bugfix)
					_short_branch_name=$(echo ${_current_branch#*${_prefix}})
				else
					if startswith "${_current_branch}" $(git config --get gitflow.prefix.hotfix); then
						SUBACTION="${SUBCOMMAND}"
						SUBCOMMAND="hotfix"
						_prefix=$(git config --get gitflow.prefix.hotfix)
						_short_branch_name=$(echo ${_current_branch#*${_prefix}})
					else
						if startswith "${_current_branch}" $(git config --get gitflow.prefix.release); then
							SUBACTION="${SUBCOMMAND}"
							SUBCOMMAND="release"
							_prefix=$(git config --get gitflow.prefix.release)
							_short_branch_name=$(echo ${_current_branch#*${_prefix}})
						fi
					fi
				fi
			fi
		fi
	fi

		if [ ! -e "$GITFLOW_DIR/git-flow-$SUBCOMMAND" ]; then
		usage
		exit 1
	fi

	# Run command
	. "$GITFLOW_DIR/git-flow-$SUBCOMMAND"
	FLAGS_PARENT="git flow $SUBCOMMAND"

	if [ -z "${SUBACTION}" ]; then
		# If the first argument is a flag, it starts with '-', we interpret this
		# argument as a flag for the default command.
		if startswith "$1" "-"; then
			SUBACTION="default"
		elif [ -z "$1" ]; then
			SUBACTION="default"
		else
			SUBACTION="$1"
			shift
			# Do not allow direct calls to subactions with an underscore.
			if $(contains "$SUBACTION" "_"); then
				warn "Unknown subcommand: '$SUBACTION'"
				usage
				exit 1
			fi
			# Replace the dash with an underscore as bash doesn't allow a dash
			# in the function name.
			SUBACTION=$(echo "$SUBACTION" |tr '-' '_')
		fi
	fi

	if ! type "cmd_$SUBACTION" >/dev/null 2>&1; then
		warn "Unknown subcommand: '$SUBACTION'"
		usage
		exit 1
	fi

	# Run the specified action
	if [ $SUBACTION != "help" ] && [ $SUBCOMMAND != "init" ]; then
		initialize
	fi
	if [ $SUBACTION != 'default' ]; then
		FLAGS_PARENT="git flow $SUBCOMMAND $SUBACTION"
	fi

	cmd_$SUBACTION "$@" "${_short_branch_name}"
}
main "$@"
